home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 592b.lha / TermII / Fran軋is / Exemples XCMD / XCMDLaser.c < prev    next >
C/C++ Source or Header  |  1991-12-22  |  10KB  |  423 lines

  1. /*
  2. *   XCMDLaser
  3. *
  4. *       XCMD pour Term II, permettant le download de fichier PostScript
  5. *       vers une LaserWriter. On utilise les propriétes suivantes de
  6. *       la LaserWriter :
  7. *
  8. *           - émettre un ^T entraine le retour du status de la laser
  9. *           - on doit émettre un ^D en fin de fichier
  10. *           - la laser répond par un ^D quand elle est prête à
  11. *             imprimer un nouveau fichier
  12. *           - émettre un ^C permet d'interrompre un job en cours
  13. *
  14. *       Pour compiler avec DICE :
  15. *
  16. *           dcc XCMDTools.o XCMDLaser.c -o XCMDLaser
  17. *
  18. */
  19.  
  20. #include <exec/types.h>
  21. #include <exec/memory.h>
  22. #include <intuition/intuition.h>
  23. #include <libraries/gadtools.h>
  24. #include <clib/exec_protos.h>
  25. #include <clib/dos_protos.h>
  26. #include <clib/asl_protos.h>
  27. #include <clib/intuition_protos.h>
  28. #include <clib/gadtools_protos.h>
  29. #include <clib/graphics_protos.h>
  30. #include <clib/alib_protos.h>
  31. #include <string.h>
  32. #include <stdio.h>
  33. #include "XCMD.h"
  34. #include "XCMDtools.h"
  35.  
  36.  
  37.  
  38. /*
  39. *   DEFINE
  40. */
  41. #define BUF_SIZE 80
  42. #define BOX 50
  43. #define TIMEOUT_LIMIT 180     /* en secondes */
  44.  
  45. /*
  46. *   VARIABLES
  47. */
  48. struct MsgPort *port = NULL;
  49. struct XCMD *XCMD = NULL;
  50. FILE *fp = NULL;
  51. const char PRINTER_EOF  = '\x04';
  52. const char INTERRUPT    = '\x03';
  53. const char STATUS_QUERY = '\x14';
  54. struct FileRequester *FileRequester = NULL;
  55. struct AslBase *AslBase = NULL;
  56. struct Library *GadToolsBase = NULL;
  57. struct IntuitionBase *IntuitionBase = NULL;
  58. struct GadgetList *glist = NULL;
  59. struct Window *window = NULL;
  60. struct Screen *screen = NULL;
  61. void *vi = NULL;
  62. struct Gadget *GadName, *GadStop;;
  63. struct TextAttr Topaz80 = { "topaz.font",8,0,0 };
  64.  
  65. /*
  66. *   PROTOS
  67. */
  68. void End(char *);
  69. void DownloadFile(char *);
  70. void ExecuteXCMD(char *, void *, void *, void *);
  71. void InitIntuition(void);
  72. long FileSize(char *);
  73. void HandleIntuition(void);
  74. void UpdateBox(long,long);
  75. void exit(int);
  76.  
  77. /*
  78. *   MAIN
  79. */
  80. int main(int argc, char *argv[])
  81.   {
  82.  
  83.   char buffer_name[256];
  84.  
  85.   /*
  86.   *  Initialisation et allocation des ressources
  87.   */
  88.   if(!FindPort("TERM"))
  89.     End("Je n'ai pas trouvé Term II");
  90.   port = CreatePort("LASER",0);
  91.   if(!port)
  92.     End("Impossible de créer mon message port");
  93.   XCMD = CreateXCMD(port);
  94.   if(!XCMD)
  95.     End("Impossible de créer la XCMD");
  96.   AslBase = OpenLibrary(AslName,36);
  97.   if(!AslBase)
  98.     End("Pas de asl.library v36 ou plus");
  99.   struct FileRequester *FileRequester = AllocAslRequest(ASL_FileRequest,NULL);
  100.   if(!FileRequester)
  101.     End("Impossible d'allouer un file requester");
  102.   InitIntuition();
  103.  
  104.  
  105.   /*
  106.   *  On sélectionne les fichiers et on les envoie à la laser
  107.   */
  108.   if(AslRequestTags(FileRequester,ASL_FuncFlags,FILF_MULTISELECT|FILF_PATGAD,
  109.     ASL_Pattern,(ULONG)"#?",
  110.     ASL_Hail,(ULONG)"Multiselect",
  111.     TAG_DONE))
  112.     {
  113.     int nb_files = FileRequester->rf_NumArgs;
  114.     if(nb_files)
  115.       {
  116.       struct WBArg *wb_arg = FileRequester->rf_ArgList;
  117.       while(nb_files--)
  118.         {
  119.         NameFromLock(wb_arg->wa_Lock,buffer_name,256);
  120.         AddPart(buffer_name,wb_arg->wa_Name,256);
  121.         DownloadFile(buffer_name);
  122.         wb_arg++;
  123.         }
  124.       }
  125.     else
  126.       {
  127.       if(FileRequester->rf_File[0] != '\0')
  128.         {
  129.         strcpy(buffer_name,FileRequester->rf_Dir);
  130.         AddPart(buffer_name,FileRequester->rf_File,256);
  131.         DownloadFile(buffer_name);
  132.         }
  133.       }
  134.     }
  135.   End("Terminé sans erreurs");
  136.   }
  137.  
  138.  
  139.  
  140.  
  141. /*
  142. *   void End(char *message)
  143. *
  144. *       Termine le programme et libère les ressources
  145. */
  146. void End(char *message)
  147.   {
  148.   puts(message);
  149.   if(XCMD)      /* Soyant sûr de remettre Term II en lecture */
  150.     {
  151.     /*  On n'utilise pas ExecuteXCMD car en cas
  152.     *   d'erreur on reviendrait ici !
  153.     */
  154.     XCMD->xcmd_Command = "serial_on";
  155.     if(SendXCMD(XCMD))
  156.       {
  157.       WaitPort(port);
  158.       GetMsg(port);
  159.       }
  160.     }
  161.   if(fp) fclose(fp);
  162.   if(XCMD) DeleteXCMD(XCMD);
  163.   if(port) DeletePort(port);
  164.   if(FileRequester) FreeAslRequest(FileRequester);
  165.   if(AslBase) CloseLibrary(AslBase);
  166.   if(window)
  167.     {
  168.     struct IntuiMessage *msg;
  169.     while(msg = GT_GetIMsg(window->UserPort)) GT_ReplyIMsg(msg);
  170.     CloseWindow(window);
  171.     }
  172.   if(vi) FreeVisualInfo(vi);
  173.   if(glist) FreeGadgets(glist);
  174.   if(screen) UnlockPubScreen(NULL,screen);
  175.   if(GadToolsBase) CloseLibrary(GadToolsBase);
  176.   if(IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
  177.   exit(0);
  178.   }
  179.  
  180.  
  181.  
  182. /*
  183. *   void DownloadFile(char *filename)
  184. *
  185. *       Download un fichier dont le nom est donné en paramètre
  186. */
  187. void DownloadFile(char *filename)
  188.   {
  189.   unsigned char write_buffer[BUF_SIZE];
  190.   char intui_buffer[60];
  191.   long file_size = FileSize(filename);
  192.   long size = 0;
  193.   sprintf(intui_buffer,"Downloading %s (%d octets)",FilePart(filename),file_size);
  194.   GT_SetGadgetAttrs(GadName,window,NULL,GTTX_Text,intui_buffer,TAG_DONE);
  195.   fp = fopen(filename,"r");
  196.   if(!fp)
  197.     End("Impossible d'ouvrir le fichier");
  198.   char c;
  199.   int i = 0;
  200.   while((c=getc(fp)) != EOF)
  201.     {
  202.     write_buffer[i] = c;
  203.     i++;
  204.     if(i == BUF_SIZE)
  205.       {
  206.       ExecuteXCMD("xcmd_swrite",write_buffer,(void *)BUF_SIZE,NULL);
  207.       size += BUF_SIZE;
  208.       HandleIntuition();
  209.       UpdateBox(size,file_size);
  210.       i = 0;
  211.       }
  212.     }
  213.   if(i>0)
  214.     ExecuteXCMD("xcmd_swrite",write_buffer,(void *)i,NULL);
  215.   /*
  216.   *  On s'assure que Term II ne lira plus le serial device
  217.   *  qu'à notre demande :
  218.   */
  219.   ExecuteXCMD("serial_off",NULL,NULL,NULL);
  220.   ExecuteXCMD("xcmd_swrite",&PRINTER_EOF,(void *)1,NULL);
  221.   size+=i;
  222.   UpdateBox(size,file_size);
  223.   /*
  224.   *     Attendre le ^D de l'imprimante, pendant au maximum
  225.   *     3 minutes
  226.   */
  227.   BOOL pas_fini = TRUE;
  228.   while(pas_fini)
  229.     {
  230.     HandleIntuition();
  231.     int i;
  232.     for(i=0; i<TIMEOUT_LIMIT; i++)
  233.       {
  234.       char eof;
  235.       ExecuteXCMD("xcmd_sread",&eof,(void *)1,(void *)1000000);
  236.       if(((long)XCMD->xcmd_Args[15])>0)
  237.         {
  238.         if(eof == PRINTER_EOF)
  239.           {
  240.           pas_fini = FALSE;
  241.           break;
  242.           }
  243.         }
  244.       HandleIntuition();
  245.       }
  246.     if(pas_fini) End("L'imprimante ne répond plus");
  247.     }
  248.   ExecuteXCMD("serial_on",NULL,NULL,NULL);
  249.   fclose(fp); fp = NULL;
  250.   GT_SetGadgetAttrs(GadName,window,NULL,GTTX_Text,NULL,TAG_DONE);
  251.   SetAPen(window->RPort,(UBYTE)0);
  252.   RectFill(window->RPort,BOX+4,58,BOX+4+242,70);
  253.   SetAPen(window->RPort,(UBYTE)3);
  254.   }
  255.  
  256.  
  257.  
  258.  
  259. /*
  260. *   void ExecuteXCMD()
  261. *
  262. *       Cette commande exécute une XCMD, et attend son retour
  263. *       ou quitte le programme en cas d'erreur
  264. */
  265. void ExecuteXCMD(char *command, void *arg1, void *arg2, void *arg3)
  266.   {
  267.   if(!XCMD) End("Pas de XCMD disponible !");
  268.   XCMD->xcmd_Command = command;
  269.   XCMD->xcmd_Args[0] = arg1;
  270.   XCMD->xcmd_Args[1] = arg2;
  271.   XCMD->xcmd_Args[2] = arg3;
  272.   if(SendXCMD(XCMD))
  273.     {
  274.     WaitPort(port);
  275.     GetMsg(port);
  276.     }
  277.   else
  278.     End("SendXCMD() a échoué");
  279.   }
  280.  
  281.  
  282.  
  283. /*
  284. * void InitIntuition()
  285. *
  286. *    Initialise Intuition, la gadget toolkit, etc...
  287. */
  288. void InitIntuition()
  289.   {
  290.   ExecuteXCMD("xcmd_lock_request",NULL,NULL,NULL);
  291.   screen = XCMD->xcmd_TermScreen;
  292.   UnLock(XCMD->xcmd_TermDir);
  293.  
  294.   IntuitionBase = OpenLibrary("intuition.library",36);
  295.   if(!IntuitionBase)
  296.     End("Pas de intuition.library v36 ou plus");
  297.  
  298.   GadToolsBase = OpenLibrary("gadtools.library",36);
  299.   if(!GadToolsBase)
  300.     End("Pas de gadtools.library v36 ou plus");
  301.  
  302.   vi = GetVisualInfo(screen, TAG_DONE);
  303.   if(!vi)
  304.     End("Impossible d'obtenir les visual infos");
  305.  
  306.   window = OpenWindowTags(NULL,
  307.     WA_Top, 20,
  308.     WA_Left, 15,
  309.     WA_DragBar, TRUE,
  310.     WA_DepthGadget, TRUE,
  311.     WA_PubScreen, screen,
  312.     WA_Width, 350,
  313.     WA_Height, 120,
  314.     WA_IDCMP, REFRESHWINDOW|TEXTIDCMP|BUTTONIDCMP,
  315.     WA_Title, "Downloading PostScript files (v1.0)",
  316.     WA_Activate, TRUE,
  317.     TAG_DONE);
  318.   if(!window)
  319.     End("Impossible d'ouvrir la fenêtre");
  320.  
  321.   struct Gadget *gad = CreateContext(&glist);
  322.   struct NewGadget ng;
  323.  
  324.   ng.ng_TextAttr = &Topaz80;
  325.   ng.ng_VisualInfo = vi;
  326.   ng.ng_LeftEdge = 10;
  327.   ng.ng_TopEdge = 30;
  328.   ng.ng_Width = 260;
  329.   ng.ng_Height = 10;
  330.   ng.ng_Flags = 0;
  331.   ng.ng_GadgetText = NULL;
  332.   gad = GadName = CreateGadget(TEXT_KIND,gad,&ng,TAG_DONE);
  333.  
  334.   ng.ng_TopEdge += 60;
  335.   ng.ng_LeftEdge = 130;
  336.   ng.ng_Height = 14;
  337.   ng.ng_Width = 100;
  338.   ng.ng_GadgetText = "STOP";
  339.   gad = GadStop = CreateGadget(BUTTON_KIND,gad,&ng,TAG_DONE);
  340.  
  341.   if(!gad)
  342.     End("La création des gadgets a échoué");
  343.  
  344.   AddGList(window,glist,-1,-1,NULL);
  345.   RefreshGList(glist,window,NULL,-1);
  346.   GT_RefreshWindow(window,NULL);
  347.  
  348.   DrawBevelBox(window->RPort,BOX,55,250,20,GT_VisualInfo,vi,GTBB_Recessed,TRUE,TAG_DONE);
  349.   }
  350.  
  351. /*
  352. * void HandleIntuition()
  353. *
  354. *   Gère les événements transmis par Intuition
  355. */
  356. void HandleIntuition()
  357.   {
  358.   struct IntuiMessage *msg;
  359.   BOOL stop = FALSE;
  360.   while(msg = GT_GetIMsg(window->UserPort))
  361.     {
  362.     ULONG class = msg->Class;
  363.     struct Gadget *gadget = msg->IAddress;
  364.     GT_ReplyIMsg(msg);
  365.     switch(class)
  366.       {
  367.       case GADGETUP :
  368.         if(gadget == GadStop)
  369.           stop = TRUE;
  370.         break;
  371.       case REFRESHWINDOW :
  372.         GT_BeginRefresh(window);
  373.         GT_EndRefresh(window,TRUE);
  374.         break;
  375.       default:
  376.         break;
  377.       }
  378.     }
  379.   if(stop)
  380.     {
  381.     ExecuteXCMD("xcmd_swrite",&INTERRUPT,(void *)1,NULL);
  382.     End("Stop by user");
  383.     }
  384.   }
  385.  
  386. /*
  387. * long FileSize(char *)
  388. *
  389. *   Retourne la taille en octets d'un fichier donné en paramètre
  390. */
  391. long FileSize(char *filename)
  392.   {
  393.   BPTR lock = Lock(filename,ACCESS_READ);
  394.   long size = 0;
  395.   if(lock)
  396.     {
  397.     struct FileInfoBlock *fib = AllocMem(sizeof(struct FileInfoBlock),MEMF_CLEAR|MEMF_PUBLIC);
  398.     if(fib)
  399.       {
  400.       Examine(lock,fib);
  401.       size = fib->fib_Size;
  402.       FreeMem(fib,sizeof(struct FileInfoBlock));
  403.       }
  404.     UnLock(lock);
  405.     }
  406.   return(size);
  407.   }
  408.  
  409.  
  410. /*
  411. * void UpdateBox(long current, long size)
  412. *
  413. *   Cette procédure met à jour la boite représentant l'état
  414. *   courant du téléchargement. current = nb d'octets déjà
  415. *   téléchargés, size = nb d'octets total.
  416. */
  417. void UpdateBox(long current, long size)
  418.   {
  419.   long width = (242 * current) / size;
  420.   RectFill(window->RPort,BOX+4,58,BOX+width+4,70);
  421.   }
  422.  
  423.